
package com.googlecode.eightqueenshaggle;

import java.util.Vector;


public class Solution {

	public Vector<Coord> queensLocations;

	// The solution needs to know, which puzzle it belongs to.
	private Puzzle myPuzzle;

	// returns the current amount of queens
	int getCurQueenCount() {

		return this.queensLocations.size();
	}

	Solution(Puzzle myPuzzle){
		
		this.myPuzzle = myPuzzle;
		
		queensLocations = new Vector<Coord>();
		
	}
	
	//serialize the queens locations into a string
	public String getCoordString()
	{
		String loc= new String();
		
		for (int i=0;i<this.getCurQueenCount();i++)
		{
			loc += this.queensLocations.get(i).x + " " + this.queensLocations.get(i).y + ";";	
		}
		
		
		return loc;		
	}
	
	//read queens locations from string and insert into object
	//serialize the queens locations into a string
	public String readCoordString(String coordString){
		
		String loc= new String();
		
		String[] coords = coordString.split(";");
		
		//TODO: make sure queensLocations is empty
		
		for (int i=0;i<coords.length;i++){
			
			int x = Integer.parseInt( coords[i].split(" ")[0] );
			int y = Integer.parseInt( coords[i].split(" ")[1] );
				
			queensLocations.add(new Coord(x , y));
			
		}
		
		
		return loc;		
	}
	
	// TODO: Can this maybe done more efficiently?
	//Check if a cell contains a queen
	public Boolean checkQueen(int x, int y){
		
		for (int k = 0; k < queensLocations.size(); k++) {

			if (queensLocations.elementAt(k).x == x &&
				queensLocations.elementAt(k).y == y) {
			
				return true;
			}
		
		}
			
		return false;
			
	}
	
	public Boolean checkFree(int x, int y){
		
		Boolean legal = true;

		// here we have some logic that might need to be modified in a later
		// version, esp for other figures than queens
		
		//check if we are still missing queens
		if(getCurQueenCount() == myPuzzle.amountQueens){
			legal = false;
			return legal;
		}

		
		// check if coordinates are within bounds
		if (x < 0 || y < 0 || x >= myPuzzle.dim1 || y >= myPuzzle.dim2) {
			legal = false;
		}

		
		//check if this queen could attack an existing queen, no queen in same ...
		for (int i = 0; i < getCurQueenCount(); i++) {

			if (x == queensLocations.get(i).x || // ... line
					y == queensLocations.get(i).y || // ... row
					Math.abs(queensLocations.get(i).x - x) == 
					Math.abs(queensLocations.get(i).y - y) // ... diagonal
			) {
				legal = false;
				return legal;
			}

		}

	
		return legal;
		
	}
	
	// add a queen if legal
	public Boolean addQueen(int x, int y) {

		//TODO: This is a copy from checkfree(...), better use this function
		Boolean legal = true;

		// here we have some logic that might need to be modified in a later
		// version, esp for other figures than queens
		
		//check if we are still missing queens
		if(getCurQueenCount() == myPuzzle.amountQueens){
			legal = false;
			return legal;
		}

		
		// check if coordinates are within bounds
		if (x < 0 || y < 0 || x >= myPuzzle.dim1 || y >= myPuzzle.dim2) {
			legal = false;
		}

		
		//check if this queen could attack an existing queen, no queen in same ...
		for (int i = 0; i < getCurQueenCount(); i++) {

			if (x == queensLocations.get(i).x || // ... line
					y == queensLocations.get(i).y || // ... row
					Math.abs(queensLocations.get(i).x - x) == 
					Math.abs(queensLocations.get(i).y - y) // ... diagonal
			) {
				legal = false;
				return legal;
			}

		}

		if (legal) {
			queensLocations.add(new Coord(x, y));
		}

		return legal;

	}

	public Boolean removeQueen(int x, int y){
		
		for(int k=0; k < myPuzzle.dim1; k++){
				if(
						queensLocations.elementAt(k).x == x &&
						queensLocations.elementAt(k).y == y
						){
					queensLocations.remove(k);
					return true;
				}
			}
		
		return false;
		
	}
	
}

// Is there sth. like this in the Java API already?
class Coord {

	public int x;
	public int y;

	Coord(int x, int y) {
		this.x = x;
		this.y = y;
	}

}

/*
 * This is how the chess board is going to be addressed. The location 0,0
 * corresponds to A1, a line corresponds to ABCD...
 * 
 * (7,0)(7,1)(7,2)(7,3)(7,4)(7,5)(7,6)(7,7)
 * (6,0)(6,1)(6,2)(6,3)(6,4)(6,5)(6,6)(6,7)
 * (5,0)(5,1)(5,2)(5,3)(5,4)(5,5)(5,6)(5,7)
 * (4,0)(4,1)(4,2)(4,3)(4,4)(4,5)(4,6)(4,7)
 * (3,0)(3,1)(3,2)(3,3)(3,4)(3,5)(3,6)(3,7)
 * (2,0)(2,1)(2,2)(2,3)(2,4)(2,5)(2,6)(2,7)
 * (1,0)(1,1)(1,2)(1,3)(1,4)(1,5)(1,6)(1,7)
 * (0,0)(0,1)(0,2)(0,3)(0,4)(0,5)(0,6)(0,7)
 */
